package com.dabai.iot.mqtt.event;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dabai.common.core.utils.DateUtils;
import com.dabai.common.core.utils.Func;
import com.dabai.iot.common.model.IotMqttMessage;
import com.dabai.iot.core.api.RemoteMessageHandlerService;
import com.dabai.iot.mqtt.model.DeviceConnectionSession;
import com.dabai.iot.mqtt.util.MqttSessionManager;
import io.vertx.mqtt.MqttEndpoint;
import io.vertx.mqtt.messages.MqttPublishMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

/**
 * 设备消息监听
 *
 * @author kev1n
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceMessageListener implements IMqttMessageListener {

    @DubboReference
    private final RemoteMessageHandlerService remoteMessageHandlerService;

    /**
     * 监听到设备发布消息
     */
    @Override
    public void onMessage(MqttEndpoint endpoint, MqttPublishMessage publishMessage) {
        StopWatch stopWatch = new StopWatch("onDeviceMessage");
        stopWatch.start();

        String traceId = IdWorker.get32UUID();
        String clientId = endpoint.clientIdentifier();
        String topic = publishMessage.topicName();
        String payload = String.valueOf(publishMessage.payload());
        Integer qos = publishMessage.qosLevel().value();
        log.info("MQTT Server ====> 收到【设备】发布消息: traceId={} clientId={} topic={} payload: {}, QoS={}", traceId, clientId, topic, payload, qos);

        if (Func.isBlank(payload)) {
            return;
        }

        DeviceConnectionSession session = MqttSessionManager.getInstance().getSession(clientId);
        if (session == null) {
            log.info("MQTT Server ====> ERROR: 收到【设备】发布消息: traceId={} clientId={}，但未找到连接会话", traceId, clientId);
            endpoint.close();
            return;
        }

        log.info("MQTT Server ====> 将设备消息发往core处理: traceId={}", traceId);
        IotMqttMessage mqttMessage = new IotMqttMessage(
            traceId,
            topic,
            payload,
            qos,
            session.getDeviceInfo().dataType(),
            DateUtils.getNowDate()
        );

        remoteMessageHandlerService.deviceMessageHandler(session.getDeviceInfo(), mqttMessage);


        stopWatch.stop();
        log.info("StopWatch ---===> [{}]: running time = {} ms", stopWatch.getId(), stopWatch.getTotalTimeMillis());
    }
}
